#include <standard/notification.h>
#include "commandmgr.h"
#include "command.h"
#include "global.h"

CCommandMgr::CCommandMgr(){
    g_pCommandMgr = this;
}
CCommandMgr::~CCommandMgr(){
    Clear();
    g_pCommandMgr = NULL;
}
void CCommandMgr::Init( class CEditorSceneMgr* pEditorSceneMgr ){
    Clear();
    m_pEditorSceneMgr = pEditorSceneMgr;
}
bool32 CCommandMgr::AddCommand( class CCommand* pCmd ){
    pCmd->m_pSceneMgr = m_pEditorSceneMgr;
	pCmd->Init();

    if (m_vCommandUndoQueue.size() >= MAXCOMMANDPOOL) {
        CCommand* _pCmd = m_vCommandUndoQueue.back();
        _pCmd->Final();
        //DELETE(_pCmd);
        m_vCommandRefList.Remove(_pCmd );
        m_vCommandUndoQueue.pop_back();
    }

    m_vCommandUndoQueue.push_front(pCmd);
    m_vCommandRefList.PushBack( pCmd );

    {
        for (list<CCommand*>::iterator it = m_vCommandRedoQueue.begin(); it != m_vCommandRedoQueue.end(); it++) {
            CCommand* _pCmd = *it;
            _pCmd->Final();
            //DELETE(_pCmd);
            m_vCommandRefList.Remove(_pCmd);
        }
    }
    m_vCommandRedoQueue.clear();
	return True;
}
bool32 CCommandMgr::Redo(){
    if (m_vCommandRedoQueue.size() > 0) {
        CCommand* _pCmd = m_vCommandRedoQueue.front();
        if (_pCmd->Redo() == True) {
            m_vCommandRedoQueue.pop_front();
            m_vCommandUndoQueue.push_front(_pCmd);
            return True;
        }
    }
    return False;
}
bool32 CCommandMgr::Undo(){
    if (m_vCommandUndoQueue.size() > 0) {
        CCommand* _pCmd = m_vCommandUndoQueue.front();
        if (_pCmd->Undo() == True) {
            m_vCommandUndoQueue.pop_front();
            m_vCommandRedoQueue.push_front(_pCmd);
            return True;
        }
    }
	return False;
}
void CCommandMgr::Clear(){
    for (list<CCommand*>::iterator it0 = m_vCommandRedoQueue.begin(); it0 != m_vCommandRedoQueue.end(); it0++) {
        CCommand* _pCmd = *it0;
        _pCmd->Final();
    }
    m_vCommandRedoQueue.clear();

    
    for (list<CCommand*>::iterator it1 = m_vCommandUndoQueue.begin(); it1 != m_vCommandUndoQueue.end(); it1++) {
        CCommand* _pCmd = *it1;
        _pCmd->Final();
    }
    m_vCommandUndoQueue.clear();


    m_vCommandRefList.Clear();
}
bool32 CCommandMgr::CanUndo(){
    return m_vCommandUndoQueue.empty() ? False : True;
}
bool32 CCommandMgr::CanRedo(){
    return m_vCommandRedoQueue.empty() ? False : True;
}